import { effect, track } from './effect'

export function computed (getterOrOptions) {
  // getterOrOptions 可以是函数，也可以是一个对象，支持get 和set
  // 当值是函数的时候不允许直接对其结果进行更改；当getterOrOptions是对象的时候通过get 和 set 进行设置
  let getter,setter
  if(typeof getterOrOptions === 'function') {
    getter = getterOrOptions
    setter = () => {
      console.warn('计算属性不允许直接更改')
    }
  } else {
    getter = getterOrOptions.get
    setter = getterOrOptions.set
  }

  return new ComputedRefImpl(getter, setter)

}
// 拦截计算属性的 value
class ComputedRefImpl {
  constructor (getter, setter) {
    // 实例化的时候直接将getter 使用effect 包住收集依赖，当里面的值变化的时候就直接触发
    this.effect = effect(getter, {lazy: true}) // effect调用的时候不调用回调函数，而是将它存起来，当触发get 的时候再调用
    // 保存setter
    this._setter = setter
  }
  get value () {
    // 依赖收集
    track(this, 'value')
    return this.effect()
  }

  set value (val) {
    this._setter(val)
  }
}
